-module(cover_test).
-export([run/0, get_info/0, dump_all/0, dump_int/0]).

-define(EXCLUDE,[cctrans0,cctrans,idtrans,treedumper,idtrans_impl1]).

reset_abc([]) -> ok;
reset_abc([M|Ms]) ->
    file:delete(atom_to_list(M)++".beam"),
    code:purge(M),
    code:delete(M),
    code:purge(M),
    reset_abc(Ms).

load_local(M, F) ->
    reset_abc([alpha, beta, gamma]),

    code:purge(M), code:delete(M), code:purge(M),
    code:load_abs(F).

run_test(CWD) ->
        file:set_cwd(CWD++"/ectsubset"),
        compile:file(idtrans2, [{cctrans, cctrans0}]),
        compile:file(cctrans2, [{cctrans, cctrans0}]),
        compile:file(idtrans2, [ect_verbose, {outdir, "tmp"}]),
        compile:file(cctrans2, [ect_verbose, {outdir, "tmp"}]),
        {ok, _} = file:read_file_info("tmp/cctrans2.stage2.ectgen.erl"),
        compile:file(idtrans2, [{d, 'ECT_UPGRADE_MODE', mode2}]),
        compile:file(cctrans2, [{d, 'ECT_UPGRADE_MODE', mode2}]),
        compile:file(idtrans2, [{d, 'ECT_UPGRADE_MODE', mode1}]),
        compile:file(cctrans2, [{d, 'ECT_UPGRADE_MODE', mode1}]),
  
        
        file:set_cwd(CWD++"/../feature_tests"),
        master:dotest(),

        file:set_cwd(CWD++"/../hcs_tests/ect2"),
        load_local(tester, "./tester"),
        tester:do_test(),
        io:format("ECT2 HCS TESTS: PASSED~n", []),
        
        file:set_cwd(CWD++"/../hcs_tests/ect2extra"),
        load_local(tester, "./tester"),
        tester:run(),
        io:format("ECT2 HCS EXTRA TESTS: PASSED~n", []),
        io:format("CHECK THAT ECT2 HCS EXTRA WAS COMPILED mode1 !!!~n", []).

run() ->
    io:format("import ect class files [to compile them later]...", []),
    import_ect:import_source(),
    io:format("ok~n", []),
    io:format("extract source code from original ect beam files [for coverage analysis]...", []),
    import_ect:reconstruct_source(),
    io:format("ok~n", []),
    cover:reset(),
    
    CoverModules = cover:compile_beam_directory("../../ect/ebin"),
    io:format("CRes= ~p~n", [CoverModules]),
    {ok, CWD} = file:get_cwd(),
    io:format("CWD=~p~n", [CWD]),
    
    try
        run_test(CWD)
    catch
        T:E ->
            io:format("ERROR ~p:~p~n~p~n", [T,E,erlang:get_stacktrace()])
    end,
    file:set_cwd(CWD),
    get_info().

print_coverinfo(CoverModules) ->
    Covers =
        lists:map(
            fun (M) ->
                {ok, Res} = cover:analyse(M, coverage, module),
                Res
            end,
            CoverModules),
    Covered = lists:sum(lists:map(fun ({_, {A,_}}) -> A end, Covers)),
    NotCovered = lists:sum(lists:map(fun ({_, {_,A}}) -> A end, Covers)),
    Totals = lists:map(fun ({Module, {C,N}}) -> {Module, {covered, C}, {notcovered, N}, {total, C+N}}  end, Covers),
    io:format("Totals=~p~nCovered=~p~nNotCovered=~p~nRatio=~p%~n", [Totals, Covered, NotCovered, 100*Covered/(Covered+NotCovered)]).

get_info() ->
    CoverModules = cover:modules(),
    io:format("TOTAL COVERAGE:~n"),
    print_coverinfo(CoverModules),
    CoverModules2 = CoverModules--?EXCLUDE,
    io:format("INTERESTING COVERAGE:~n"),
    print_coverinfo(CoverModules2).


dump(L) ->
    lists:map(
        fun (M) -> cover:analyse_to_file(M) end,
        L).

dump_all() ->
    dump(cover:modules()).

dump_int() ->
    dump(cover:modules()--?EXCLUDE).